package com.dmbjz.restaurants.service;


import cn.hutool.core.bean.BeanUtil;
import com.dmbjz.common.constant.RedisKeyConstant;
import com.dmbjz.common.model.entity.Restaurant;
import com.dmbjz.common.utils.AssertUtil;
import com.dmbjz.restaurants.dao.RestaurantDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashMap;
import java.util.concurrent.TimeUnit;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class RestaurantService {

    @Autowired
    public RestaurantDao restaurantMapper;
    @Autowired
    public RedisTemplate redisTemplate;



    /*根据餐厅 ID 查询餐厅数据*/
    public Restaurant findById(Integer restaurantId) {

        AssertUtil.isTrue(restaurantId == null, "请选择餐厅查看");                         // 请选择餐厅
        String key = RedisKeyConstant.restaurants.getKey() + restaurantId;                             // 获取 Key
        LinkedHashMap restaurantMap = (LinkedHashMap) redisTemplate.opsForHash().entries(key);        // 获取餐厅缓存

        /*如果缓存不存在，查询数据库*/
        Restaurant restaurant = null;
        if (restaurantMap == null || restaurantMap.isEmpty()) {

            log.info("缓存失效了，查询数据库：{}", restaurantId);
            restaurant = restaurantMapper.findById(restaurantId);
            redisTemplate.setEnableTransactionSupport(true);    //开启事务
            if (restaurant != null) {
                redisTemplate.opsForHash().putAll(key, BeanUtil.beanToMap(restaurant));  // 更新缓存
            } else {

                Restaurant tempNull = new Restaurant("","",0f,0f,"","","","","","","","","","",0,0,0);
                redisTemplate.execute(new SessionCallback<Object>() {
                    @Override
                    public Object execute(RedisOperations operations) throws DataAccessException {
                        operations.multi();                                                 // 标记事务块的开始
                        operations.opsForHash().putAll(key,BeanUtil.beanToMap(tempNull));  // 写入缓存一个空数据，设置一个失效时间，60s
                        operations.expire(key,60, TimeUnit.SECONDS);
                        return operations.exec();                                         // 执行以 {multi()} 开始的事务中的所有排队命令。
                    }
                });

            }
        } else {
            restaurant = BeanUtil.fillBeanWithMap(restaurantMap,new Restaurant(), false);
        }
        return restaurant;
    }



}
